﻿package  {
	import flash.display.Stage;	
	import flash.display.DisplayObject;
	public class Grid {
		
		// Constants:
		public static const offsetX:Number = 246; //X Offset of the grid on the flash application
		public static const offsetY:Number = 40; //Y Offset of the grid on the flash application
		public static const unitX:Number = 32; // Width of a grid space
		public static const unitY:Number = 32; // Height of a grid space
		public static const width:Number = 8*unitX; //Width of the grid
		public static const height:Number = 16*unitY; //Height of the grid
		// Public Properties:
		public var gridArray:Array;
		public var deadList:Array;
		
		// Private Properties:
	
		// Initialization:
		public function Grid():void{
			gridArray = new Array(8*16);
			deadList = new Array();
		}
		// Public Methods:
		//Checks to see if there is an orb at the xy location
		public function hasOrbThere(tempGridX:Number, tempGridY:Number):Boolean{
			if(gridArray[(tempGridY*8)+tempGridX] != null){
				return true;
			}else{
				return false;
			}
		}
		
		//returns an orb at a particular location.
		public function getOrbAt(tempX,tempY):Orb{
			return gridArray[(tempY*8)+tempX];
		}
		
		//Inserts a nanogroup at the top of the grid.
		public function addNanoGroup(group:NanoGroup):void{
			var pos1:Number = (group.getOrbOne().getGridY()*8)+group.getOrbOne().getGridX();
			gridArray[pos1] = group.getOrbOne();
			
			var pos2:Number = (group.getOrbTwo().getGridY()*8)+group.getOrbTwo().getGridX();
			gridArray[pos2] = group.getOrbTwo();
		}
		
		//Adds an orb at a specified location on the grid.
		public function addFuseOrb(orb:Orb):void{
			var pos:Number = (orb.getGridY()*8)+orb.getGridX();
			gridArray[pos] = orb;
		}
		
		//Detaches NanoOrbs from groups if the NanoOrb is dead
		//Places all dead orbs in an array for clearing and removes their
		//reference from the grid.
		public function clearDeadOrbs():int {
			var scoreCount:int = 0;
			for(var i:int = 0; i < gridArray.length;i++){
				if(gridArray[i] != null){
					if(!gridArray[i].getAlive()){
						if(gridArray[i] is NanoOrb && gridArray[i].getAttached()){
							switch(gridArray[i].getPartnerLocal()){
								case "up":{
									gridArray[i-8].setAttached(false);
									break;
								}
								case "right":{
									gridArray[i+1].setAttached(false);
									break;
								}
								case "down":{
									gridArray[i+8].setAttached(false);
									break;
								}
								case "left":{
									gridArray[i-1].setAttached(false);
									break;
								}
								default:{
									break;
								}
							}
						}
						if (gridArray[i] is FuseOrb) {
							scoreCount++;
						}
						deadList.push(gridArray[i]);
						gridArray[i] = null;
					}
				}
			}
			return scoreCount;
		}
		//Checks the grid for any matches of four and sets the corresponding orbs'
		// alive parameters to false.
		public function checkOrbs():void{
			for(var i:int=0; i < (gridArray.length/16); i++){
				for(var k:int=0; k < (gridArray.length/8)-3; k++){
					if(hasOrbThere(i,k) && hasOrbThere(i,k+1) && hasOrbThere(i,k+2) && hasOrbThere(i,k+3)){
						if(getOrbAt(i,k).getType() == getOrbAt(i,k+1).getType() && getOrbAt(i,k).getType() == getOrbAt(i,k+2).getType() && getOrbAt(i,k).getType() == getOrbAt(i,k+3).getType()){
							getOrbAt(i,k).setAlive(false);
							getOrbAt(i,k+1).setAlive(false);
							getOrbAt(i,k+2).setAlive(false);
							getOrbAt(i,k+3).setAlive(false);
						}
					}
				}
			}//end for loop
			
			for(var a:int=0; a < 16; a++){
				for(var s:int=0; s < 5; s++){
					if(hasOrbThere(s,a) && hasOrbThere(s+1,a) && hasOrbThere(s+2,a) && hasOrbThere(s+3,a)){
						if(getOrbAt(s,a).getType() == getOrbAt(s+1,a).getType() && getOrbAt(s,a).getType() == getOrbAt(s+2,a).getType() && getOrbAt(s,a).getType() == getOrbAt(s+3,a).getType()){
							getOrbAt(s,a).setAlive(false);
							getOrbAt(s+1,a).setAlive(false);
							getOrbAt(s+2,a).setAlive(false);
							getOrbAt(s+3,a).setAlive(false);
						}
					}
				}
			}//end for loop
		}
		
		//Shifts all unattached NanoOrbs or unobstructed NanoGroups down one grid position
		public function adjustOrbs():Boolean{
			var temp:NanoOrb;
			var tempBool:Boolean;
			tempBool = false;
			for(var i:int=gridArray.length; i > 0; i--){
				if(gridArray[i] != null && gridArray[i] is NanoOrb){
					if (gridArray[i + 8] == null) {
						if(!gridArray[i].getAttached() && gridArray[i].getGridY() != 15){
							gridArray[i].setGridY(gridArray[i].getGridY()+1);
							temp = gridArray[i];
							gridArray[i] = null;
							gridArray[i + 8] = temp;
							tempBool = true;
						} else if (gridArray[i].getAttached && gridArray[i].getGridY() != 15) {
							switch(gridArray[i].getPartnerLocal()) {
								case "up" : {
									gridArray[i].setGridY(gridArray[i].getGridY() + 1);
									gridArray[i-8].setGridY(gridArray[i-8].getGridY() + 1);
									
									temp = gridArray[i];
									gridArray[i] = null;
									gridArray[i + 8] = temp;
									
									temp = gridArray[i-8];
									gridArray[i-8] = null;
									gridArray[i] = temp;
									tempBool = true;
									break;
								}
								case "down" : {
									//Will always catch the up case first
									break;
								}
								case "left" : {
									if (gridArray[i + 7] == null) {
										gridArray[i].setGridY(gridArray[i].getGridY() + 1);
										gridArray[i-1].setGridY(gridArray[i-1].getGridY() + 1);
										
										temp = gridArray[i];
										gridArray[i] = null;
										gridArray[i + 8] = temp;
										
										temp = gridArray[i-1];
										gridArray[i-1] = null;
										gridArray[i+7] = temp;
										tempBool = true;
										break;
									}
									break;
								}
								case "right" : {
									//will always catch the left case first
									break;
								}
							}
						}
					}
				}
			}
			return tempBool;
		}
		// Private Methods:
	}
	
}